import { reactive } from "vue";
import { Uint16, Uint32, u16, u32, u8 } from "./codec/codec_type";
import { RecvFrame } from "./recv";
import { Cmd } from "./proto";
import { ByteView } from "./codec/byte_view";
import { u16toHex, u32toHex } from "./utils";

export class PartsStatus {

    cookingRoomLed: boolean;
    cookingRoomFan: boolean;
    radiateFan: boolean;
    drainPump: boolean;
    v1: boolean;
    v2: boolean;
    v3: boolean;
    v4: boolean;
    v5: boolean;
    v6: boolean;
    v7: boolean;
    v8: boolean;
    waterHeat: boolean;
    steamHeat: boolean;
    drawPump: boolean;

    constructor(status: Uint16) {
        this.cookingRoomLed = status.isSet(0);
        this.cookingRoomFan = status.isSet(1);
        this.radiateFan = status.isSet(2);
        this.drainPump = status.isSet(3);
        this.v1 = status.isSet(4);
        this.v2 = status.isSet(5);
        this.v3 = status.isSet(6);
        this.v4 = status.isSet(7);
        this.v5 = status.isSet(8);
        this.v6 = status.isSet(9);
        this.v7 = status.isSet(10);
        this.v8 = status.isSet(11);
        this.waterHeat = status.isSet(12);
        this.steamHeat = status.isSet(13);
        this.drawPump = status.isSet(14);
    }
};

export class TempStatus {
    value: number;
    internvalValue: number;
    scv: boolean;
    scg: boolean;
    oc: boolean;

    constructor(v: Uint32) {
        let temp = (v.value >> 18) & 0x3FFF;
       
        if ((temp & 0x2000) != 0x00) {
            this.value = -(0x4000 - temp) * 0.25;
        } else {
            this.value = temp * 0.25;
        }
       
        temp = (v.value >> 4) & 0xFFF;
        if (temp & 0x800) {
            this.internvalValue = -(0x1000 - temp) * 0.0625;
        } else {
            this.internvalValue = temp * 0.0625;
        }

        this.scv = v.isSet(2);
        this.scg = v.isSet(1);
        this.oc = v.isSet(0);
    }
};

export class SensorStatus {
    waterLevelHigh: boolean;
    waterLevelLow: boolean;
    goSwitch: boolean;
    leak1: boolean;
    leak2: boolean;
    bowlChecked: boolean;
    nozzleAlm: boolean;
    nozzleOrigin: boolean;
    nozzleOrigin2: boolean;
    doorSensor: boolean;
    doorStatus: boolean;

    constructor(v: Uint16) {
        this.waterLevelHigh = v.isSet(0);
        this.waterLevelLow = v.isSet(1);
        this.goSwitch = v.isSet(2);
        this.leak1 = v.isSet(3);
        this.leak2 = v.isSet(4);
        this.bowlChecked = v.isSet(5);
        this.nozzleAlm = v.isSet(6);
        this.nozzleOrigin = v.isSet(7);
        this.nozzleOrigin2 = v.isSet(8);
        this.doorSensor = v.isSet(9);
        this.doorStatus = v.isSet(10);
    }
};

export class DrawHeatStatus {
    drawState: string;
    waterHeatState: string;
    steamHeatState: string;

    constructor(draw: number, water: number, steam: number) {
        switch (draw) {
            case 0: this.drawState = '抽水中'; break;
            case 1: this.drawState = '超时'; break;
            case 2: this.drawState = '停止'; break;
            case 3: this.drawState = '空闲'; break;
            default: this.drawState = '状态未知'; break;
        }
        switch (water) {
            case 0: this.waterHeatState = '加热中'; break;
            case 1: this.waterHeatState = '空闲'; break;
            case 2: this.waterHeatState = '停止'; break;
            case 3: this.waterHeatState = '超时'; break;
            case 4: this.waterHeatState = '故障'; break;
            default: this.waterHeatState = '状态未知'; break;
        }
        switch (steam) {
            case 0: this.steamHeatState = '加热中'; break;
            case 1: this.steamHeatState = '空闲'; break;
            case 2: this.steamHeatState = '停止'; break;
            case 3: this.steamHeatState = '超时'; break;
            case 4: this.steamHeatState = '故障'; break;
            default: this.steamHeatState = '状态未知'; break;
        }
    }
}

export class Status {

    version = '';
    pasrtStatus = new PartsStatus(u16());
    flowMeterCount = 0;
    waterTemp = new TempStatus(u32());
    steamTemp = new TempStatus(u32());
    kpa = 0;
    sensor = new SensorStatus(u16());
    drawHeat = new DrawHeatStatus(0, 0, 0);
};

export const globalStatus = reactive<Status>(new Status());

function on_status(frame: RecvFrame) {
    const version = u16();
    const parts = u16();
    const flow = u16();
    const waterTemp = u32();
    const steamTemp = u32();
    const steamKpa = u16();
    const sensor = u16();
    const draw = u8();
    const water = u8();
    const steam = u8();
    frame.parse_notify(
        version, parts, flow, waterTemp, steamTemp, steamKpa, sensor,
        draw, water, steam
    );
    globalStatus.version = u16toHex(version.value);
    globalStatus.pasrtStatus = new PartsStatus(parts);
    globalStatus.flowMeterCount = flow.value;
    globalStatus.waterTemp = new TempStatus(waterTemp);
    globalStatus.steamTemp = new TempStatus(steamTemp);
    globalStatus.kpa = steamKpa.value;
    globalStatus.sensor = new SensorStatus(sensor);
    globalStatus.drawHeat = new DrawHeatStatus(draw.value, water.value, steam.value);
}

function on_log(frame: RecvFrame) {
    const bw = new ByteView([], 0, 0);
    frame.parse_notify(bw);
    const msg = bw.toString();
    console.log(`log:${msg}`);
}

export function handle_notify(frame: RecvFrame) {
    switch (frame.cmd()) {
        case Cmd.STATUS: on_status(frame); break;
        case Cmd.LOG: on_log(frame); break;
    }
}

export function handle_notify_ack(frame: RecvFrame) {

}


